package com.sxbbc.common.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.function.common.GetRest;
import com.function.common.RestResponse;
import com.sxbbc.common.basics.exceptions.ThrowJsonException;
import com.sxbbc.common.basics.push.PushVo;
import com.sxbbc.common.basics.service.redis.RedisUtilsService;
import com.sxbbc.common.basics.utils.calculation.CalcuUtils;
import com.sxbbc.common.basics.utils.statics.StaticUtils;
import com.sxbbc.common.core.entity.jz.BankDetail;
import com.sxbbc.common.core.entity.jz.CCustomer;
import com.sxbbc.common.core.entity.jz.SysCashDetails;
import com.sxbbc.common.core.entity.jz.SysCashRule;
import com.sxbbc.common.core.enums.CashTypeEnums;
import com.sxbbc.common.core.enums.HandleTypeEnums;
import com.sxbbc.common.core.enums.ParamEnums;
import com.sxbbc.common.core.enums.PushTypeEnums;
import com.sxbbc.common.core.mapper.jz.SysCashDetailsMapper;
import com.sxbbc.common.core.service.*;
import com.sxbbc.common.core.utils.BasePage;
import com.sxbbc.common.core.utils.MsgUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 提现申请记录表 服务实现类
 * </p>
 *
 * @author leehao
 * @since 2019-04-30
 */
@Service
public class SysCashDetailsServiceImpl extends ServiceImpl<SysCashDetailsMapper, SysCashDetails> implements ISysCashDetailsService {
	@Autowired
	private IBankDetailService bankDetailService;
	@Autowired
	private ISysCashRuleService sysCashRuleService;
	@Autowired
	private SysCashDetailsMapper sysCashDetailsMapper;
	@Autowired
	private IAccountChangeService accountChangeService;
	@Autowired
	private IPushService pushService;
	@Autowired
	private RedisUtilsService redisUtilsService;
	@Autowired
	private ICCustomerService icCustomerService;
	@Autowired
	private IInfoParamService infoParamService;


	@Override
	public BasePage<SysCashDetails> queryCashDetails(BasePage<SysCashDetails> page, SysCashDetails details) {
		QueryWrapper<SysCashDetails> wrapper = queryWrapper(details);
		wrapper.orderByDesc("create_time");
		if (page.isPaging()) {
			super.page(page, wrapper);
		} else {
			List<SysCashDetails> list = super.list(wrapper);
			page.setRecords(list);
		}
		for (SysCashDetails cashDetail : page.getRecords()) {
			cashDetail.setCashTypeName(CashTypeEnums.getName(cashDetail.getType()));
			//推荐人信息
			CCustomer customer = icCustomerService.getMineParent(cashDetail.getTargetId());
			if(customer != null) {
				if(CalcuUtils.getInstance().isEquals(customer.getAuthen(), StaticUtils.STATUS_YES)) {
					cashDetail.setParentName(customer.getRealName());
				}else {
					cashDetail.setParentName("未认证"+customer.getPhone());
				}
			}else {
				cashDetail.setParentName("无推荐人");
			}
		}
		return page;
	}

	@Override
	public RestResponse editCashApplyStatus(Integer id, Integer status, String remark) {
		CalcuUtils calcuUtils = CalcuUtils.getInstance();
		SysCashDetails cash = super.getById(id);
		if (status != null && calcuUtils.isEquals(cash.getStatus(),StaticUtils.STATUS_SUCCESS)) {
			return GetRest.getFail("该申请已通过，请勿重复提交");
		}
		if (status != null && calcuUtils.isEquals(cash.getStatus(),StaticUtils.STATUS_FAIL)) {
			return GetRest.getFail("该申请已驳回，请勿重复提交");
		}
		PushVo vo = null;
		if (calcuUtils.isEquals(status,StaticUtils.STATUS_FAIL)) {
			String msg = "";
			if (calcuUtils.isEquals(cash.getType(), CashTypeEnums.CUSTOMER.getId())) {
				// 用户提现
				msg = accountChangeService.insertCMoneyDetail(cash.getTargetId(), HandleTypeEnums.CASH.getId(),
						StaticUtils.PAY_IN, cash.getPayCode(), cash.getCashMoney(), "用户提现驳回", null);
				//消息推送 极光推送 本版本使用token作为alias
				String token = redisUtilsService.getKey(cash.getTargetId() + "_token");
				vo = new PushVo(token,MsgUtils.JPUSH_0004,PushTypeEnums.CASH_NOTICE.getId(),
						String.valueOf(cash.getId()),new String[]{cash.getCashMoney().toString()},cash.getTargetId());
				pushService.pushMessageById(vo);
			} else if (calcuUtils.isEquals(cash.getType(), CashTypeEnums.BUSINESS.getId())) {
				// 商家提现
				msg = accountChangeService.insertBMoneyDetail(cash.getTargetId(), HandleTypeEnums.CASH.getId(),
						StaticUtils.PAY_IN, cash.getPayCode(), cash.getCashMoney(), "商家提现驳回", null);
			}else if(calcuUtils.isEquals(cash.getType(), CashTypeEnums.AGENT.getId())){
				msg = accountChangeService.insertAgMoneyDetail(cash.getTargetId(), HandleTypeEnums.CASH.getId(),
						StaticUtils.PAY_IN, cash.getPayCode(), cash.getCashMoney(), "代理提现驳回", null);
			}
			if (!StringUtils.isEmpty(msg)) {
				throw new ThrowJsonException(msg);
			}
		}else if(calcuUtils.isEquals(status,StaticUtils.STATUS_SUCCESS)){
			if (calcuUtils.isEquals(CashTypeEnums.CUSTOMER.getId(),cash.getType())) {
				CCustomer customer = icCustomerService.getById(cash.getTargetId());
				if(customer == null){
					return GetRest.getFail("用户不存在！");
				}

				//企业付款到银行卡
				/*BankDetail bankDetail = bankDetailService.getById(cash.getBankId());
				if(bankDetail == null){
					return GetRest.getFail("请求错误，错误代码001");
				}
				BankType type = bankTypeService.getById(bankDetail.getTypeId());
				if(type == null){
					return GetRest.getFail("请求错误，错误代码002");
				}

				//微信付款以分为单位，需要放大100倍
				BigDecimal payMoney = CalcuUtils.getInstance().mul(cash.getRealMoney(), new BigDecimal(100), 0);
				boolean paraTrans = WxPayUtils.getInstance().getPayParaTransToBankcard(type.getWxBankCode(),cash.getBankCode(),cash.getRealName(),
						String.valueOf(payMoney),cash.getPayCode());
				if(!paraTrans){
					return GetRest.getSuccess("企业付款操作失败");
				}*/

				//消息推送 极光推送 本版本使用token作为alias
				String token = redisUtilsService.getKey(cash.getTargetId() + "_token");
				vo = new PushVo(token,MsgUtils.JPUSH_0003,PushTypeEnums.CASH_NOTICE.getId(),
						String.valueOf(cash.getId()),new String[]{cash.getCashMoney()+"",cash.getRealMoney()+""},cash.getTargetId());
				pushService.pushMessageById(vo);
			}
		}
		// 增加驳回备注
		if (calcuUtils.isEquals(status,StaticUtils.STATUS_FAIL)) {
			cash.setRemark(remark);
		}
		cash.setStatus(status);
		boolean save = super.updateById(cash);
		if (!save) {
			throw new ThrowJsonException("审核失败");
		}
		return GetRest.getSuccess("审核操作成功");
	}

	/**
	 * 提现申请查询条件
	 *
	 * @param details 页面查询条件
	 * @return com.baomidou.mybatisplus.mapper.EntityWrapper<com.sxbbc.common.core.entity.jz.SysCashDetails>
	 * @author leehao
	 */
	private QueryWrapper<SysCashDetails> queryWrapper(SysCashDetails details) {
		QueryWrapper<SysCashDetails> wrapper = new QueryWrapper<>();
		if (StringUtils.isNotBlank(details.getQueryTime())) {
			String[] times = details.getQueryTime().split("~");
			wrapper.apply(true,"date_format(create_time,'%Y-%m-%d') >= {0}",times[0].trim());
			wrapper.apply(true,"date_format(create_time,'%Y-%m-%d') <= {0}",times[1].trim());
		}
		if(StringUtils.isNotBlank(details.getPayCode())){
			wrapper.eq("pay_code",details.getPayCode());
		}
		if (details.getStatus() != null) {
			wrapper.eq("status", details.getStatus());
		}
		if (details.getTargetId() != null) {
			wrapper.eq("target_id", details.getTargetId());
		}
		if (details.getType() != null) {
			wrapper.eq("type", details.getType());
		}
		if(StringUtils.isNotBlank(details.getRealName())) {
			wrapper.like("real_name", details.getRealName());
		}
		if(StringUtils.isNotBlank(details.getPhone())) {
			wrapper.like("phone", details.getPhone());
		}
		return wrapper;
	}

	/**
	 * 提现申请
	 * @param cashDetails
	 * @return
	 */
	@Override
	public RestResponse handleCashApply(SysCashDetails cashDetails) {
		CalcuUtils calcuUtils = CalcuUtils.getInstance();

		BankDetail bankDetail = bankDetailService.getById(cashDetails.getBankId());
		if (bankDetail == null) {
			return GetRest.getFail("请选择提现银行卡");
		}

		// 获取提现规则
		SysCashRule queryCashRule = new SysCashRule();
		queryCashRule.setRoleType(cashDetails.getType());
		List<SysCashRule> list = sysCashRuleService.list(sysCashRuleService.queryWrapper(queryCashRule));
		SysCashRule cashRule = list.get(0);
		if (!calcuUtils.isEquals(StaticUtils.STATUS_YES, cashRule.getIsOpen())) {
			return GetRest.getFail("提现通道暂时关闭");
		}
		BigDecimal cashMoney = cashDetails.getCashMoney();
		if (cashMoney == null || cashMoney.compareTo(cashRule.getMinVal()) < 0
				|| cashMoney.compareTo(cashRule.getMaxVal()) > 0) {
			return GetRest.getFail("提现金额不在"+cashRule.getMinVal()+"~"+cashRule.getMaxVal()+"提现范围");
		}
		if (cashMoney.doubleValue() % cashRule.getMultiple() != 0) {
			return GetRest.getFail("提现金额必须为" + cashRule.getMultiple() + "的整数倍");
		}
		// 限制每日提现次数
		if (!calcuUtils.isEquals(StaticUtils.CASH_NO_TYPE, cashRule.getType())) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("targetId", cashDetails.getTargetId());
			map.put("type", cashDetails.getType());
			map.put("cashType", cashRule.getType());
			Integer num = sysCashDetailsMapper.getRuleNums(map);
			if (num > cashRule.getNum()) {
				return GetRest.getFail("提现次数已达上限");
			}
		}

		// 限制每日提现累计金额
		Map<String,Object> map = new HashMap<>();
		map.put("dateType", StaticUtils.DAY_DATA);
		map.put("targetid",cashDetails.getTargetId());
		//查询用户当天已经提现到账金额
		BigDecimal totalTodayCashMoney = sysCashDetailsMapper.sumRealMoney(map);
		BigDecimal total = calcuUtils.add(totalTodayCashMoney,cashMoney,2);
		//平台设置当天提现上限金额
		BigDecimal cashToAccountByDay = calcuUtils.getValueByClass(BigDecimal.class,infoParamService.getValueByCode(ParamEnums.CUSTOMER_CASHTOACCOUNTBYDAY));
		if(total.compareTo(cashToAccountByDay) > 0){
			return GetRest.getFail("当天提现金额已达上限！");
		}


		//1、扣除用户账号余额
		String payCode = calcuUtils.getOrderCode("CASH");
		String msg = "";
		// 用户提现
		if (calcuUtils.isEquals(cashDetails.getType(), CashTypeEnums.CUSTOMER.getId())) {
			msg = accountChangeService.insertCMoneyDetail(cashDetails.getTargetId(), HandleTypeEnums.CASH.getId(),
					StaticUtils.PAY_OUT, payCode, cashMoney, "用户提现扣除", null);
		} else if (calcuUtils.isEquals(cashDetails.getType(), CashTypeEnums.BUSINESS.getId())) {
			// 商家提现
			msg = accountChangeService.insertBMoneyDetail(cashDetails.getTargetId(), HandleTypeEnums.CASH.getId(),
					StaticUtils.PAY_OUT, payCode, cashMoney, "商家提现扣除", null);
		}else if (calcuUtils.isEquals(cashDetails.getType(), CashTypeEnums.AGENT .getId())) {
			// 代理提现
			msg = accountChangeService.insertAgMoneyDetail(cashDetails.getTargetId(), HandleTypeEnums.CASH.getId(),
					StaticUtils.PAY_OUT, payCode, cashMoney, "代理提现扣除", null);
		}
		if (!StringUtils.isEmpty(msg)) {
			throw new ThrowJsonException(msg);
		}

		//2、提现申请记录
		// 税
		BigDecimal taxmoney = calcuUtils.mul(cashMoney, cashRule.getScale(), 2);
		// 实际应该到账金额
		BigDecimal realmoney = calcuUtils.sub(cashMoney, taxmoney, 2);
		SysCashDetails details = new SysCashDetails();
		details.setPayCode(payCode);
		details.setTargetId(cashDetails.getTargetId());
		details.setRealName(bankDetail.getRealName());
		details.setIdCard(bankDetail.getIdcard());
		details.setBankName(bankDetail.getBankName());
		details.setBankCode(bankDetail.getBankCard());
		details.setPhone(bankDetail.getPhone());
		details.setBankAddr(bankDetail.getBankAddr());
		details.setCashMoney(cashMoney);
		details.setRealMoney(realmoney);
		details.setType(cashDetails.getType());
		details.setBankId(cashDetails.getBankId());

		//3、AA判断提现金额小于平台设置的自动到账金额，那么无须审核，自动到账
		/*BigDecimal customerCashAutoToAccount = calcuUtils.getValueByClass(BigDecimal.class,infoParamService.getValueByCode(ParamEnums.CUSTOMER_CASHAUTOTOACCOUNT));
		if(customerCashAutoToAccount.compareTo(cashMoney) > 0){
			//提现操作到账操作
			//提现记录修改状态
			details.setStatus(StaticUtils.STATUS_SUCCESS);
		}*/
		int result = sysCashDetailsMapper.insert(details);
		if (result < 1) {
			throw new ThrowJsonException("提现申请操作失败");
		}
		return GetRest.getSuccess("提现申请操作成功");
	}
}
